<?php
namespace app\event;

use app\model\UserModel;
use GatewayWorker\Lib\Gateway;
use think\facade\Cache;
use Workerman\Worker;

/**
 * Worker 命令行服务类
 */
class ChatEvents
{
    /**
     * onWorkerStart 事件回调
     * 当businessWorker进程启动时触发。每个进程生命周期内都只会触发一次
     *
     * @access public
     * @param  \Workerman\Worker    $businessWorker
     * @return void
     */
    public static function onWorkerStart(Worker $businessWorker)
    {
        foreach (config('bootstrap', []) as $class_name) {
            /** @var \Webman\Bootstrap $class_name */
            $class_name::start($businessWorker);
        }
        Cache::tag('im')->clear();

    }

    /**
     * onMessage 事件回调
     * 当客户端发来数据(Gateway进程收到数据)后触发
     *
     * @access public
     * @param  int       $client_id
     * @param  mixed     $data
     * @return void
     */
    public static function onMessage($client_id, $data)
    {
        $message = json_decode($data, true);
        $message_type = $message['type'];
        switch($message_type) {
            case 'init':
                $init_message = array(
                    'message_type' => 'init',
                    'client_id' => $client_id,
                );
                Gateway::sendToClient($client_id, json_encode($init_message));
                return;
            case 'ping':
                $pong_message = array(
                    'message_type' => 'pong',
                    'client_id'    => $client_id,
                    'timestamp'    => time()
                );
                Gateway::sendToClient($client_id, json_encode($pong_message));
                self::ping($client_id,$message['platform']);
                return;
            default:
                $error_message = array(
                    'message' => 'unknown message'
                );
                Gateway::sendToClient($client_id, json_encode($error_message));
        }
    }

    /**
     * onClose 事件回调 当用户断开连接时触发的方法
     *
     * @param  integer $client_id 断开连接的客户端client_id
     * @return void
     */
    public static function onClose($client_id)
    {
        $userModel = new UserModel();
        $_user_id = Cache::get($client_id);
        $_app_client_id = Cache::get(strval($_user_id).'_app_client_id');
        $_user_client_lst = Cache::get(strval($_user_id));
        if($_user_client_lst){
            unset($_user_client_lst[array_search($client_id,$_user_client_lst)]);
            $_user_client_lst = array_values($_user_client_lst);
            if(count($_user_client_lst)==0){
                Cache::delete(strval($_user_id));
                Cache::delete(strval($_user_id).'_app_client_id');
                $userModel->where(['user_id'=>$_user_id])->update(['logout_timestamp'=>time(),'online_status'=>'offline','app_online_status'=>'offline']);
            }
            else{
                Cache::tag('im')->set(strval($_user_id),$_user_client_lst);
                if($_app_client_id==$client_id){
                    Cache::delete(strval($_user_id).'_app_client_id');
                    $userModel->where(['user_id'=>$_user_id])->update(['logout_timestamp'=>time(),'online_status'=>'online','app_online_status'=>'offline']);
                }
                else{
                    $userModel->where(['user_id'=>$_user_id])->update(['logout_timestamp'=>time(),'online_status'=>'online','app_online_status'=>'online']);
                }
            }
        }
        else{
            Cache::delete(strval($_user_id).'_app_client_id');
            $userModel->where(['user_id'=>$_user_id])->update(['logout_timestamp'=>time(),'online_status'=>'offline','app_online_status'=>'offline']);
        }
        Cache::delete($client_id);
    }

    public static function ping($client_id,$platform){
        $_user_id = Gateway::getUidByClientId($client_id);

        Cache::tag('im')->set($client_id,strval($_user_id));
        if($_user_id){
            if($platform=='app'){
                Cache::tag('im')->set(strval($_user_id).'_app_client_id',$client_id);
            }
            $userModel = new UserModel();

            $_user_client_lst = Cache::get(strval($_user_id));
            if($_user_client_lst){
                array_push($_user_client_lst,$client_id);
                $_user_client_lst = array_values(array_unique($_user_client_lst));
                Cache::tag('im')->set(strval($_user_id),$_user_client_lst);
            }
            else{
                Cache::tag('im')->set(strval($_user_id),[$client_id]);
            }

            $userModel->where(['user_id'=>$_user_id])->update(['logout_timestamp'=>time(),'online_status'=>'online']);
        }

    }

    /**
     * onWorkerStop 事件回调
     * 当businessWorker进程退出时触发。每个进程生命周期内都只会触发一次。
     *
     * @param  \Workerman\Worker    $businessWorker
     * @return void
     */
    public static function onWorkerStop(Worker $businessWorker)
    {
        Cache::tag('im')->clear();
    }
}